/*
 * FS.c
 *
 *  Created on: 18/09/2011
 *      Author: Luca - Anahi
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>


#include "FS.h"
#include "definFat32.h"
#include "listas.h"
#include "utils.h"
#include "estructuras.h"


/**** Iniciar FAT ****/

t_fat32 *iniciar_fat32(const char *path) {
	t_fat32 *fat32 = malloc(sizeof(t_fat32));
	struct stat buffer; //da info de un fichero sin abrirlo, pero si es un link simbólico lo sigue hasta el fichero real.
	fat32->fsFileDescriptor = open(path, O_RDWR);

	if (fat32->fsFileDescriptor == -1) {
		perror("Error al abrir");
		exit(EXIT_SUCCESS);
	}
//lo mismo que stat(),pero para un fichero ya abierto y, por tanto, tengamos el descriptor de fichero correspondiente
	if (fstat(fat32->fsFileDescriptor, &buffer) == -1) {
		perror("Error al devolver información, fstat");
		exit(EXIT_SUCCESS);
	}

	if (!S_ISREG(buffer.st_mode)) {                      /* Pregunta si es un archivo regular, común */
		fprintf(stderr, "%s no es un archivo\n", path);
		exit(EXIT_SUCCESS);
	}


	fat32->fS = mmap(0, buffer.st_mode, PROT_READ | PROT_WRITE, MAP_SHARED, fat32->fsFileDescriptor, 0);

	/* Esto me devuelve el puntero al File System propiamente dicho en la variable fS.
	   A partir de ahora puedo trabajar con nuestro File System :) */

	if (fat32->fS == MAP_FAILED) {
		perror("Error al hacer el mmap");
		exit(EXIT_SUCCESS);
	}


	/****               Inicialización del bootsector              ****/

	memcpy(&fat32->bootSector, fat32->fS, sizeof(t_bootsector));

	/* Guardo en el contenido del puntero bootSector el tamaño de área correspondiente al mismo. */


	/****         	Inicialización del FS Information sector       ****/

	fat32->baseAddrOfFSystemInfo = fat32->fS + fat32->bootSector.sectorsFSInfoSector * fat32->bootSector.bytesPSector;
	fat32->fileSystemInfo.numberFreeClusters = -1;
	fat32->fileSystemInfo.mostRecentlyAllocatedCluster = 0xFFFFFFFF;

	memcpy(&fat32->fileSystemInfo, fat32->baseAddrOfFSystemInfo, sizeof(t_fsinfosector));


	/****                  Inicialización del FAT                  ****/

	fat32->fatTable = (uint32_t*) (fat32->fS + fat32->bootSector.reservedSectorCount * fat32->bootSector.bytesPSector);
	fat32->tamFat = fat32->bootSector.sectorsPerFAT * fat32->bootSector.bytesPSector;   // Consola - fsinfo
	fat32->numberOfFATEntries = fat32->tamFat / ENTRY_SIZE;

	fat32->tamCluster = fat32->bootSector.sectorsPCluster * fat32->bootSector.bytesPSector;   // Consola - fsinfo
	fat32->entradasXcluster = fat32->tamCluster / ENTRY_SIZE;


	/**** 				Inicialización de los directorios          ****/

	fat32->rootDirectoryContent = crear_lista();
	uint32_t numeroCluster = fat32->bootSector.clustersRootDirectory;
	cargar_entradas(fat32, numeroCluster, fat32->rootDirectoryContent);

	return fat32;

}


/**** Operaciones ****/

/**** Obtener la cantidad de clusters libres ****/  /* Consola - fsinfo*/

unsigned int obtener_cant_clusters_libres(t_fat32 *fat32) {
	int i;
	unsigned int cantidad;

	cantidad = 0;

	for(i=0; i < fat32->numberOfFATEntries; i++) {
		if (fat32->fatTable[i] == FREE_CLUSTER) {
			cantidad++;
		}
	}

	return cantidad;
}



/**** Obtener la cantidad de clusters ocupados ****/  /* Consola - fsinfo*/

unsigned int obtener_cant_clusters_ocupados(t_fat32 *fat32) {
	int i;
	unsigned int cantidad;

	cantidad = 0;

	for(i=0; i < fat32->numberOfFATEntries; i++) {
		if (fat32->fatTable[i] == EOC_VALUE) {      /* o USED_CLUSTER? */
			cantidad++;
		}
	}

	return cantidad;
}



/**** Obtener un cluster libre de la tabla FAT ****/

uint32_t obtener_cluster_libre(t_fat32 *fat32) {
	int i;

	for(i=0; i < fat32->numberOfFATEntries; i++) {
		if(fat32->fatTable[i] == FREE_CLUSTER) {
			fat32->fatTable[i] = EOC_VALUE;
			return i;
		}
	}

	return 0;
}



/**** Obtener el contenido de un cluster en base al número del cluster ****/

char *obtener_contenido_cluster(t_fat32 *fat32, int numeroCluster) {
	uint32_t RSC = fat32->bootSector.reservedSectorCount * fat32->bootSector.bytesPSector;   /* Reserved Sector Count, offset 0x0E * Bytes per sector, offset 0x0B */
	uint32_t FS = fat32->bootSector.sectorsPerFAT * fat32->tamFat;   /* Tamaño de la FAT, offset 0x10 * offset 0x24 */
	uint32_t SC = fat32->bootSector.sectorsPCluster * fat32->bootSector.bytesPSector;   /* Tamaño del cluster, offset 0x0D * offset 0x0B */
	char *direccion_Cluster = fat32->fS + FS + RSC + (numeroCluster - 2) * SC;

	return direccion_Cluster;
}



/**** Obtener el cluster siguiente a una cadena de clusters ****/

uint32_t obtener_sgte_cluster(t_fat32 *fat32, uint32_t clusterActual) {
		if (fat32->fatTable[clusterActual] == EOC_VALUE) {
			return 0;
		}

		return fat32->fatTable[clusterActual];
}



/****Configurar bytes altos y bajos en primer cluster ****/

t_file_entry *config_HiandLo(t_file_entry *entrada, uint32_t cluster){
	entrada->highFirstCluster = (cluster >> 16) & 0x0000FFFF;
	entrada->lowFirstCluster  = cluster & 0x0000FFFF;
	return entrada;
}



/**** Configurar primer cluster ****/

void configurar_primerCluster_archivo(t_fat32 *fat32, t_elem_archivo *elemento,  uint32_t clusterLibre){

	char *direccion_Cluster = obtener_contenido_cluster(fat32, elemento->campoFat.sourceClusterNumber);
	char *entradaArchivo = NULL;
	entradaArchivo= direccion_Cluster + ENTRY_SIZE * elemento->campoFat.sourceClusterEntryNumber;

	// configuro los campos Hi y Low en la entrada al root, ya que es el primer cluster agregado a ese archivo.
	config_HiandLo((t_file_entry*)entradaArchivo, clusterLibre);
	elemento->campoFat.firstCluster = clusterLibre;

}



/**** Agregar uno o varios clusters a una cadena de clusters ****/

bool agregar_clusters_libres(t_fat32 *fat32, t_element_fat *elemento, int cantClusters){

	uint32_t clusterIni = elemento->firstCluster;
	int i;

	if (clusterIni == 0) {
		uint32_t clusterLibre = obtener_cluster_libre(fat32);



		if( elemento->tipo == ENTRY_FILE) {

			configurar_primerCluster_archivo(fat32, (t_elem_archivo*)elemento, clusterLibre);     /* El primer cluster necesita ser configurado previamente antes de almacenar la información, es sólo para archivos */
		}

		clusterIni = clusterLibre;

		cantClusters --;

	}

	if ((!fat32->fatTable[clusterIni] == EOC_VALUE)){

		do {

			clusterIni = obtener_sgte_cluster(fat32,clusterIni);   /* En el clusterIni se devuelve el contenido del mismo, que es la referencia al siguiente cluster */


		} while ((!fat32->fatTable[clusterIni] == EOC_VALUE));
	}

	for (i=0; i< cantClusters; i++) {

		uint32_t clusterLibre = obtener_cluster_libre(fat32);
		fat32->fatTable[clusterIni] = clusterLibre;
		clusterIni = clusterLibre;
	}

	return true;
}



/**** Remover clusters ****/

bool remover_cluster(t_fat32 *fat32, t_element_fat *elemento, int cantClusters){
	uint32_t iCluster = elemento->firstCluster;
	t_listaClusters *lista = crear_lista_clusters();
	t_listaClusters *aux;
	int i;

	agregar_cluster_lista(lista, iCluster);

	if ((!fat32->fatTable[iCluster] == EOC_VALUE)){
			do {

				iCluster = obtener_sgte_cluster(fat32,iCluster);
				agregar_cluster_lista(lista, iCluster);

			} while ((!fat32->fatTable[iCluster] == EOC_VALUE));
	}

	for (i=0; i < cantClusters; i++) {

		aux = lista;
		while(aux != NULL){
			aux = aux->sgte;
		}
		fat32->fatTable[aux->cluster] = FREE_CLUSTER;
		free(aux);
	}

	aux = lista;
	while(aux != NULL){
		aux = aux->sgte;
	}
	fat32->fatTable[aux->cluster] = EOC_VALUE;
	free(lista);

	return true;
}



/**** Funciones de Horas y Fechas ****/

//Los campos que contienen fechas utilizan 16 bits (dos bytes) para codificar el día, mes y año de la fecha
//en cuestión, pero referidas a 1980. Es decir, al año expresado deberá sumársele 1980 para obtener la fecha
//correcta. De los 16 bits utilizados, llamaremos bit 0 al menos significativo, y bit 16 al mas significativo

void get_fecha_archivo(t_date fecha, uint16_t byteFecha) {
	fecha.year  = (uint16_t)((byteFecha >> 9)+ 1980);			  	//Bits 9-15: Años transcurridos desde 1980, valores en el rango 0..127
	fecha.month = (uint16_t)((byteFecha >> 5) & (uint16_t)0xF); 	//Bits 5-8: Número de mes, valores en el rango 1..12
	fecha.day   = (uint16_t)((byteFecha) & (uint16_t)0x1F);	        //Bits 0-4: Día del mes, valores en el rango 1..31

}

void get_tiempo_archivo(t_time horario, uint16_t byteTiempo) {
	horario.hours 		= (uint16_t)(byteTiempo >> 11);							//Bits 11-15: Numero de horas, en el rango 0..23
	horario.minutes		= (uint16_t)((byteTiempo >> 5) & (uint16_t)0x3F); 		//Bits 5-10: Numero de minutos, en el rango 0..59
	horario.seconds		= (uint16_t)((byteTiempo) & (uint16_t)0x1F)*2; 	 		//Bits 0-4: Numero de 2 * segundos, en el rango 0..29 (0..58 segundos).
}



/**** Configurar nombre para las estructuras t_element_fat y t_entry ****/

void configurar_name(char *nombreElemento,char *nombrePosta,char *extension, char *nombreEntry, uint16_t tamEntrada){
	int contador = 0;

	if (nombreEntry != NULL && tamEntrada >0) {			//Chequea que el nombreEntry y tamEntrada no se hayan modificado antes y estén en 0.
		memcpy(nombreElemento, nombrePosta, tamEntrada);
		return;
	}

	for (contador = 0; (nombrePosta[contador] != '\0') && contador < 7; contador ++); // Cuenta la cantidad de caracteres que tiene el nombre y que sea menor a 8.

	// Aca abajo copia primero el nombre del archivo, y luego su extensión correspondiente.
		memcpy(nombreElemento, nombrePosta, contador);
		memcpy(nombreElemento + contador + 1, extension, 3);
}



/**** Lectura de los elementos de la FAT ****/

//Te llega una operación de lectura. Lo que se debe hacer es: buscar en el root cluster una entrada de
//directorio. todo
void lectura_de_elemento(t_entry *entrada, t_element_fat *elemento, char* nombreEntry, uint16_t tamEntrada){


	get_fecha_archivo(elemento->creationDate,entrada->createDate);
	get_tiempo_archivo(elemento->creationTime,entrada->createTime);

	configurar_name(elemento->nombreEntrada, entrada->fileName, entrada->fileExtension, nombreEntry, tamEntrada);
	elemento->nombre_length = tamEntrada;

// Unís el FstClusHI y FstClusLO, y con eso sabes donde esta el cluster que contiene el contenido de ese
//directorio, acá buscas una entrada de archivo, unís FstClusHI y FstClusLO para saber donde esta el
//contenido del archivo para poder devolverlo.

	elemento->firstCluster = entrada->highFirstCluster;
	elemento->firstCluster = (elemento->firstCluster<<16) & 0xFFFF0000;
	elemento->firstCluster = elemento->firstCluster | entrada->lowFirstCluster;

}



/**** Lectura de la entrada del archivo ****/

t_elem_archivo *leer_entrada_archivo(t_fat32 *fat32, t_file_entry  *entrada, char *nombreEntrada, uint16_t tamEntrada) {
	t_elem_archivo *archivo = malloc(sizeof(t_elem_archivo));
	archivo->campoFat.tipo = ENTRY_FILE;						/* Luego de crear una estructura de Archivo, al subcampo de campoFat le asigno su tipo correspondiente */
	lectura_de_elemento(entrada,&archivo->campoFat,nombreEntrada,tamEntrada);
	archivo->tamFile = entrada->fileSize;
	/* Despues de la lectura de la estructura de entrada al directorio le asigno el tamaño  al archivo
	creado. De esta manera cargo los datos de la entrada al directorio raiz al archivo. */

	return archivo;

}



/**** Lectura de entrada Long File Name ****/

uint16_t leer_entrada_LFN(t_fat32 *fat32, uint32_t numeroCluster, int *iEntrada, char *nombreEntrada){
	t_longFileName_entry *lfn_entry = (t_longFileName_entry*) obtener_contenido_cluster(fat32, numeroCluster) + *iEntrada * ENTRY_SIZE;
	unsigned int sizeCadenaUTF8 = strlen(nombreEntrada);

	do {

		uint16_t cadenaUTF16[13];           // Sólo van a entrar 13 caracteres, que en utf16 serán 26 bytes, 2 bytes por caracter, por eso uint16_t
		unsigned int sizeCadenaUTF16 = 13;  // Duda: se usa este tamaño?

		// Abajo se copian las tres partes que conforman el nombre en la entrada lfn en la cadena UTF16
		// La primera parte del nombre tiene 5 caracteres utf16, la segunda 6 y la tercera 2
		// El valor uint16_t en el sizeof hace referencia a que en la cadena entran 2 bytes por caracter

		memcpy(cadenaUTF16, lfn_entry->nameCharacters, 5 * sizeof(uint16_t));
		memcpy(cadenaUTF16 + 5, lfn_entry->nameCharacters2, 6 * sizeof(uint16_t));
		memcpy(cadenaUTF16 + 5 + 6, lfn_entry->nameCharacters3, 2 * sizeof(uint16_t));


		unicode_utf16_to_utf8_inbuffer(cadenaUTF16, sizeCadenaUTF16, nombreEntrada , &sizeCadenaUTF8); // Toma la cadena UTF16 y su tamaño, lo transforma en utf8 para que podamos interpretarlo y lo guarda en el nombreEntrada

		lfn_entry = (t_longFileName_entry*) obtener_contenido_cluster(fat32, numeroCluster) + *iEntrada * ENTRY_SIZE;   // Lee la siguiente entrada LFN

		*iEntrada = *iEntrada +1;

	} while(lfn_entry->sequenceNumbers != 0x40);   //Se usa este valor porque representa que es la última entrada lfn, sin embargo es la primera entrada lfn que se ve cuando se lee el archivo de directorio

	*iEntrada = *iEntrada -1; // Luego de convertir la entrada long file name para leerla, volvemos al principio de la entrada, ya que esta cada una consta de varias entradas

	return sizeCadenaUTF8;
}



/**** Lectura de entrada de un directorio ****/

t_elem_directorio *leer_entrada_directorio(t_fat32 *fat32, t_dir_entry *entrada, char *nombreEntrada, uint16_t tamEntrada) {
	t_elem_directorio *directorio = malloc(sizeof(t_elem_directorio));

	directorio->campoFat.tipo = ENTRY_DIRECTORY;
	lectura_de_elemento(entrada, &directorio->campoFat, nombreEntrada, tamEntrada);
	directorio->l_clusters = crear_lista();

    //Acá se fija que el directorio contenga subdirectorios o archivos adentro. De ser así, procede a seguir leyendo.
	if((directorio->campoFat.firstCluster > 0) && strncmp(entrada->fileName, ".       ", 8) != 0 && strncmp(entrada->fileName, "..      ", 8) != 0)
	{
		cargar_entradas(fat32, directorio->campoFat.firstCluster, directorio->l_clusters); //recursivamente.
	}
	return directorio;
}



/**** Cargar en memoria las entradas de archivos, directorios o nombre largo ****/
/*
t_entry crear_estructura_entrada(char *cadena_entrada){
	t_entry *nueva = malloc(sizeof(t_entry));
	strncpy(nueva->fileName, cadena_entrada, 8);
	nueva->fileExtension = (cadena_entrada[8]+cadena_entrada[9]+cadena_entrada[10]);
	return nueva;
}
*/

//Debe saber leer cualquier tipo de entrada y las sub-entradas de un directorio.
//Es decir, yo te debería poder pasar un path cualquiera y vos deberías saber encontrar ese archivo
//( si es que existe ). Tecnicamente debería ser una función que reconozca las entradas de un cluster
//y en caso de ser un directorio debería poder llamarse recursivamente.


uint32_t cargar_entradas(t_fat32 *fat32, uint32_t numeroCluster, t_lista *entradas){
	char nombreEntrada[NAME_SIZE];
	char *direccionCluster = obtener_contenido_cluster(fat32, numeroCluster);
	uint16_t tamEntrada = 0;
	int iEntrada = 0;		// Es la variable que va a permitir posicionarnos en la entrada del directory table que queremos.
	char *entrada = NULL;

	memset(nombreEntrada, 0, NAME_SIZE);   // Pone ceros en todos los caracteres del nombreEntrada, inicialización

	do{
		entrada = direccionCluster + ENTRY_SIZE * iEntrada; // Devuelve la posicion de la entrada al directory table.
		if(entrada[0] == DIR_ENTRY_LIBRE){
			iEntrada++;
		}

		switch(entrada[11]){   		// Se fija en entrada[11] que es el offset 0x0B, "atributos", asi distinguimos entre los distintos tipos de entrada

			case ARCHIVE:{
				t_elem_archivo *archivo = leer_entrada_archivo(fat32,(t_file_entry*)entrada, nombreEntrada, tamEntrada);

				archivo->campoFat.sourceClusterNumber = numeroCluster;
				archivo->campoFat.sourceClusterEntryNumber = iEntrada;

				if(archivo != NULL){
					agregar_elemento_lista(entradas, archivo);
				}
				memset(nombreEntrada, 0, NAME_SIZE);
				tamEntrada = 0;
				break;
			}
			case SUBDIRECTORY:{
				t_elem_directorio *directorio = leer_entrada_directorio(fat32,(t_dir_entry*)entrada, nombreEntrada, tamEntrada);

				directorio->campoFat.sourceClusterNumber = numeroCluster;
				directorio->campoFat.sourceClusterEntryNumber = iEntrada;

				if(directorio != NULL){
					agregar_elemento_lista(entradas, directorio);  // hacer función. Se usa este valor porque representa que es la última entrada lfn, sin embargo es la primera entrada lfn que se ve cuando se lee el archivo de directorio
				}

				memset(nombreEntrada, 0, NAME_SIZE);
				tamEntrada = 0;
				break;
			}
			case LFN_ENTRY:{  			// Tiene un tratamiento distinto que los archivos o directorios.
				tamEntrada = leer_entrada_LFN(fat32, numeroCluster, &iEntrada, nombreEntrada);
				// Se pasa iEntrada como dirección de memoria ya que dentro de la función se usa iEntrada como puntero
				break;
			}
			default:{
				fprintf(stderr, "No se puede cargar la entrada");
				break;
			}
		}

		iEntrada++;

		if(iEntrada == fat32->entradasXcluster){                         //Si se llega al límite del cluster, se obtiene el siguiente
			numeroCluster = obtener_sgte_cluster(fat32, numeroCluster);
			direccionCluster = obtener_contenido_cluster(fat32, numeroCluster);
			iEntrada = 0;
		}


	}while(entrada[0] != 0x00);

	return 0;
}



/**** Creación de entrada Long File Name ****/

t_longFileName_entry *crear_entrada_LFN(t_fat32 *fat32, uint32_t numeroCluster, int iEntrada, char *nombreEntrada){
	t_longFileName_entry *lfn_entry = (t_longFileName_entry*) obtener_contenido_cluster(fat32, numeroCluster) + iEntrada * ENTRY_SIZE;
	uint16_t cadenaUTF16[13];               // Sólo van a entrar 13 caracteres, que en utf16 serán 26 bytes, 2 bytes por caracter, por eso uint16_t
	unsigned int sizeCadenaUTF16 = 13;

	unicode_utf8_to_utf16_inbuffer(nombreEntrada, strlen(nombreEntrada), cadenaUTF16, &sizeCadenaUTF16); // Toma el nombreEntrada y su tamaño, lo transforma en utf16 y lo guarda en cadenaUTF16
	// El parámetro 4 de la función de arriba es una dirección de destino del buffer por lo que se pasa tamBuffer como dirección de memoria

	lfn_entry->attributes = LFN_ENTRY;
	lfn_entry->sequenceNumbers = 0x40; // Se usa este valor porque representa que es la última entrada lfn, sin embargo es la primera entrada lfn que se ve cuando se lee el archivo de directorio

	// Abajo se copia la conversión guardada en la cadenaUTF16 en las tres partes que conforman el nombre en la entrada lfn
	// La primera parte del nombre tiene 5 caracteres utf16, la segunda 6 y la tercera 2
	// El valor uint16_t en el sizeof hace referencia a que en la cadena entran 2 bytes por caracter

	memcpy(lfn_entry->nameCharacters, cadenaUTF16, 5 * sizeof(uint16_t));
	memcpy(lfn_entry->nameCharacters2, cadenaUTF16 + 5, 6 * sizeof(uint16_t));
	memcpy(lfn_entry->nameCharacters3, cadenaUTF16 + 5 + 6, 2 * sizeof(uint16_t));

	return lfn_entry;
}

/* A TERMINAR
bool es_directorio(t_entry *entrada, char *nombre){
		if(entrada->fileAttributes == SUBDIRECTORY){
			return true;
		}else{
			return false;
		}
}

uint32_t unirHi_Lo(t_entry *entrada){
	uint32_t cluster;// = malloc(sizeof(uint32_t));
	cluster = entrada->highFirstCluster;
	cluster = (entrada->highFirstCluster) << 16 & 0xFFFF0000;
	cluster = cluster | entrada->lowFirstCluster;
	return cluster;
}

void imprimir_listado(t_campoLista *lista){
	while(lista!=NULL){
		t_element_fat *elemento = lista->algo;
		char *nombre = elemento->nombreEntrada;
		printf("%s\n" ,nombre);
		lista = lista->sgte;
	}
	return;
}

*/

//Falta terminar
void *buscar_enRoot(t_fat32 *fat32, char *path){
	int i,index = 0;
	char *root = obtener_contenido_cluster(fat32, 2); //Me posiciono en el 1 sector del root.
	char *entrada;
	char **vector = string_split2( path ,'/');
	int cantElem = sizeof(vector)/sizeof(char);
	void *elemento;
	entrada = root + ENTRY_SIZE*index;


	while ((entrada[0]!= 0)&&(i<=cantElem)){
		switch (entrada[11]){
			char *nombre = ((t_entry*)entrada)->fileName;

		case ARCHIVE :{
			if((i==cantElem)&& (strcmp(nombre,vector[cantElem])==0)){
					uint32_t numeroCluster = unirHi_Lo((t_entry*)entrada); //uno para acceder a la entrada del archivo y leer su contenido.
					char *direccionCluster;
					direccionCluster = obtener_contenido_cluster(fat32, numeroCluster);
					t_elem_archivo *archivo = leer_entrada_archivo(fat32,(t_file_entry*)entrada, vector[cantElem],0);
					archivo->campoFat.sourceClusterNumber = numeroCluster;
					archivo->campoFat.sourceClusterEntryNumber = index;
					if(archivo != NULL){
						elemento = archivo;
					}
			}
				i= cantElem + 1;
			break;
		}
		case SUBDIRECTORY:{
			if(strcmp(nombre, vector[cantElem])== 0){
				uint32_t numeroCluster = unirHi_Lo((t_entry*)entrada); //uno para acceder a la entrada de los demás directorios.
				char *direccionCluster;
				direccionCluster = obtener_contenido_cluster(fat32, numeroCluster);
				if(i!=cantElem){
					entrada = direccionCluster;
					i++;
				}else{
					t_elem_directorio *directorio= leer_entrada_directorio(fat32,(t_dir_entry*)entrada,vector[cantElem],0);
					directorio->campoFat.sourceClusterNumber = numeroCluster;
					directorio->campoFat.sourceClusterEntryNumber = index;
					elemento = directorio;
					i = cantElem + 1;
				}
			}
			break;
		}
		}
		}
		}

	return entrada;
}


/****	Listar Directorios ****/ //Falta terminar

void listar_directorio(t_fat32 *fat32, char *path){

	char **vector = string_split2(path,'/'); 			//vector con los directorios a llegar
	int tamVector = sizeof(vector)/sizeof(char);		//cant de elementos del vector

	char *entrada = buscar_enRoot(fat32,path,vector,tamVector);// puntero al inicio del root.(Sector 1 del cluster 2).


	if(entrada[0] == 0){
		printf("ls: no se puede acceder a %s : No existe el fichero o el directorio", path);
	}else{
		if(((t_entry*)entrada)->fileAttributes == SUBDIRECTORY){
		char *nombreDirectorio = vector[tamVector];
		t_elem_directorio *directorio = leer_entrada_directorio(fat32, (t_entry*)entrada, nombreDirectorio, 0);

			if(directorio->l_clusters->cantElementos == 0){
				printf("El directorio %s está vació", path);
			}else{
				imprimir_listado(directorio->l_clusters->ptro);
			}
		}else {
			printf("ls: no se puede acceder a %s : No existe el fichero o el directorio", path);
		}
	}
	free(vector);
}



/**** Truncar archivo ****/
/*

void truncar_archivo(t_fat32 *fat32, char *path, off_t length){
	char **vector = string_split2(path,'/');
	int i = sizeof(vector)/sizeof(char);

	t_elem_archivo *archivo = buscar_enRoot(fat32, path, vector, i);

	int cantClusters = length / (SECTOR_SIZE * SECTOR_P_CLUSTER);


	if(archivo->tamFile > (archivo->tamFile - length)){
		remover_cluster(fat32, &archivo->campoFat, cantClusters);
	}else{
		agregar_clusters_libres(fat32, &archivo->campoFat, cantClusters);
	}

	return;

}
*/

/**** Renombrar archivo ****/
/*
void renombrar_archivo(t_fat32 *fat32, char *pathNombreAntiguo, char *pathNombreNuevo){
	char **arrayPathAntiguo = string_split2(pathNombreAntiguo, '/');
	char **arrayPathNuevo = string_split2(pathNombreNuevo, '/');
	unsigned int i, tamPathA, tamPathN = 0;

	while(arrayPathAntiguo[i] != '\0'){
		tamPathA++;
		i++;
	}
	i = 0;

	while(arrayPathNuevo[i] != '\0'){
		tamPathN++;
		i++;
	}

	if(tamPathA == tamPathN){    // La operación entonces es rename
		t_entry *entrada_p_modificar = buscar_enRoot(fat32, pathNombreAntiguo, arrayPathAntiguo, tamPathA);
		memcpy(entrada_p_modificar->fileName, arrayPathNuevo[tamPathN] , 8);
		memcpy(entrada_p_modificar->fileExtension, arrayPathNuevo[tamPathN] + 9 , 3);

	}else{						// La operación entonces es mv


	}

	return;
}


*/

/*                      LEER ARCHIVO CONFIG       */
config leerConfig (char* archivoDeConfiguracion){

	config Conf;
	char* saraza = (char*) malloc (20);
	FILE *punteroAConfig;
	punteroAConfig = fopen(archivoDeConfiguracion, "r+");


	fscanf(punteroAConfig, "%s %i", saraza, &Conf.ip);
	fscanf(punteroAConfig, "%s %i", saraza, &Conf.puerto);
	fscanf(punteroAConfig, "%s %i", saraza, &Conf.cantConexiones);
	fscanf(punteroAConfig, "%s %i", saraza, &Conf.cache);

	fclose (punteroAConfig);
	free (saraza);

	return Conf;

}
